#ifndef __SHAPE_H__
#define __SHAPE_H__

#include "vec.h"
#include <utility>
using std::pair;

//* ----- Type Definition -----
typedef vec3 Point3D;

class Shape {
protected:
	//! Shape translation
	vec3 position;

	//! Shape rotation
	double azimuthX;
	double azimuthY;
	double azimuthZ;

	//! Shape size
	double height;
	double width;
	double depth;

	//! Shape rotate vectors
	vec3 rotateX;
	vec3 rotateY;
	vec3 rotateZ;

public:

	//! Creates the Bounding Volume structure of this Shape
	/*! Returns a pair of points that represents the Bounding Volume
	 */
	pair<Point3D, Point3D> getBoundingVolume();

	//! Executes a rotation of the object in X direction
	/*! Calculates the new position and sum the azimuthX
	 */
	void rotX(double angle, double axisX, double axisY, double axisZ);
	
	//! Executes a rotation of the object in Y direction
	/*! Calculates the new position and sum the azimuthY
	 */
	void rotY(double angle, double axisX, double axisY, double axisZ);
	
	//! Executes a rotation of the object in Z direction
	/*! Calculates the new position and sum the azimuthZ
	 */
	void rotZ(double angle, double axisX, double axisY, double axisZ);

	///----------------- GETTERS AND SETTERS -----------------

	//! Returns the private field position
	/*! Used to encapsulate the field
	 */
	vec3 getPosition();

	//! Returns the private field rotateX
	/*! Used to encapsulate the field
	 */
	vec3 getRotateX();

	//! Returns the private field rotateY
	/*! Used to encapsulate the field
	 */
	vec3 getRotateY();

	//! Returns the private field rotateZ
	/*! Used to encapsulate the field
	 */
	vec3 getRotateZ();

	//! Returns the private field azimuthX
	/*! Used to encapsulate the field
	 */
	double getAzimuthX();

	//! Returns the private field azimuthY
	/*! Used to encapsulate the field
	 */
	double getAzimuthY();

	//! Returns the private field azimuthZ
	/*! Used to encapsulate the field
	 */
	double getAzimuthZ();

	//! Returns the private field height
	/*! Used to encapsulate the field
	 */
	double getHeight();

	//! Returns the private field width
	/*! Used to encapsulate the field
	 */
	double getWidth();

	//! Returns the private field depth
	/*! Used to encapsulate the field
	 */
	double getDepth();

	//! Changes the private field position
	/*! Used to encapsulate the field
	 *  @param newPos the new position of the shape
	 */
	void setPosition(vec3 newPos);

	//! Changes the private field azimuth
	/*! Used to encapsulate the field
	 *  @param azimuth the new shape azimuth
	 */
	void setAzimuthX(double azimuth);

	//! Changes the private field azimuth
	/*! Used to encapsulate the field
	 *  @param azimuth the new shape azimuth
	 */
	void setAzimuthY(double azimuth);

	//! Changes the private field azimuth
	/*! Used to encapsulate the field
	 *  @param azimuth the new shape azimuth
	 */
	void setAzimuthZ(double azimuth);

	//! Changes the private field height
	/*! Used to encapsulate the field
	 *  @param height the new shape height
	 */
	void setHeight(double height);

	//! Changes the private field height
	/*! Used to encapsulate the field
	 *  @param height the new shape height
	 */
	void setWidth(double width);

	//! Changes the private field depth
	/*! Used to encapsulate the field
	 *  @param depth the new shape depth
	 */
	void setDepth(double depth);
};

#endif
